#include "../Core/OpCode.h"

void InitOpCode_0x4_0x7(){
	//////////////////////////////////////////////////
	//		INC AX   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x40){
		OP_CODE_1({
			reg->AX = FlagOperation::ADD(Mem, reg, reg->AX, 1);
		},
		{
			re->string = "INC AX";
		})
	};
	
	//////////////////////////////////////////////////
	//		INC CX   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x41){
		OP_CODE_1({
			reg->CX = FlagOperation::ADD(Mem, reg, reg->CX, 1);
		},
		{
			re->string = "INC CX";
		})
	};
	
	//////////////////////////////////////////////////
	//		INC DX   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x42){
		OP_CODE_1({
			reg->DX = FlagOperation::ADD(Mem, reg, reg->DX, 1);
		},
		{
			re->string = "INC DX";
		})
	};
	
	//////////////////////////////////////////////////
	//		INC BX   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x43){
		OP_CODE_1({
			reg->BX = FlagOperation::ADD(Mem, reg, reg->BX, 1);
		},
		{
			re->string = "INC BX";
		})
	};
	
	//////////////////////////////////////////////////
	//		DEC AX   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x48){
		OP_CODE_1({
			reg->AX = FlagOperation::SUB(Mem, reg, reg->AX, 1);
		},
		{
			re->string = "DEC AX";
		})
	};
	
	//////////////////////////////////////////////////
	//		DEC CX   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x4B){
		OP_CODE_1({
			reg->CX = FlagOperation::SUB(Mem, reg, reg->CX, 1);
		},
		{
			re->string = "DEC CX";
		})
	};
	
	//////////////////////////////////////////////////
	//		DEC DX   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x49){
		OP_CODE_1({
			reg->DX = FlagOperation::SUB(Mem, reg, reg->DX, 1);
		},
		{
			re->string = "DEC DX";
		})
	};
	
	//////////////////////////////////////////////////
	//		DEC BX   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x4A){
		OP_CODE_1({
			reg->BX = FlagOperation::SUB(Mem, reg, reg->BX, 1);
		},
		{
			re->string = "DEC BX";
		})
	};

	//////////////////////////////////////////////////
	//		PUSH AX   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x50){
		OP_CODE_1({
			WordSetToByte(reg->AX, VMtoRM(Mem, reg->SS, reg->SP-2), VMtoRM(Mem, reg->SS, reg->SP-1));
			reg->SP = reg->SP - 2;
		}, 
		{
			re->string = "PUSH AX";
		})
	};

	//////////////////////////////////////////////////
	//		PUSH CX   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x51){
		OP_CODE_1({
			WordSetToByte(reg->CX, VMtoRM(Mem, reg->SS, reg->SP-2), VMtoRM(Mem, reg->SS, reg->SP-1));
			reg->SP = reg->SP - 2;
		}, 
		{
			re->string = "PUSH CX";
		})
	};

	//////////////////////////////////////////////////
	//		PUSH DX   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x52){
		OP_CODE_1({
			WordSetToByte(reg->DX, VMtoRM(Mem, reg->SS, reg->SP-2), VMtoRM(Mem, reg->SS, reg->SP-1));
			reg->SP = reg->SP - 2;
		}, 
		{
			re->string = "PUSH DX";
		})
	};
	
	//////////////////////////////////////////////////
	//		PUSH BX   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x53){
		OP_CODE_1({
			WordSetToByte(reg->BX, VMtoRM(Mem, reg->SS, reg->SP-2), VMtoRM(Mem, reg->SS, reg->SP-1));
			reg->SP = reg->SP - 2;
		}, 
		{
			re->string = "PUSH BX";
		})
	};

	//////////////////////////////////////////////////
	//		PUSH SP   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x54){
		OP_CODE_1({
			WordSetToByte(reg->SP, VMtoRM(Mem, reg->SS, reg->SP-2), VMtoRM(Mem, reg->SS, reg->SP-1));
			reg->SP = reg->SP - 2;
		}, 
		{
			re->string = "PUSH SP";
		})
	};

	//////////////////////////////////////////////////
	//		PUSH BP   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x55){
		OP_CODE_1({
			WordSetToByte(reg->BP, VMtoRM(Mem, reg->SS, reg->SP-2), VMtoRM(Mem, reg->SS, reg->SP-1));
			reg->SP = reg->SP - 2;
		}, 
		{
			re->string = "PUSH BP";
		})
	};
	
	//////////////////////////////////////////////////
	//		PUSH SI   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x56){
		OP_CODE_1({
			WordSetToByte(reg->SI, VMtoRM(Mem, reg->SS, reg->SP-2), VMtoRM(Mem, reg->SS, reg->SP-1));
			reg->SP = reg->SP - 2;
		}, 
		{
			re->string = "PUSH SI";
		})
	};

	//////////////////////////////////////////////////
	//		PUSH DI   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x57){
		OP_CODE_1({
			WordSetToByte(reg->DI, VMtoRM(Mem, reg->SS, reg->SP-2), VMtoRM(Mem, reg->SS, reg->SP-1));
			reg->SP = reg->SP - 2;
		}, 
		{
			re->string = "PUSH DI";
		})
	};

	//////////////////////////////////////////////////
	//		POP AX   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x58){
		OP_CODE_1({
			ByteSetToWord(&reg->AX, *VMtoRM(Mem, reg->SS, reg->SP), *VMtoRM(Mem, reg->SS, reg->SP+1));
			reg->SP = reg->SP + 2;
		}, 
		{
			re->string = "POP AX";
		})
	};

	//////////////////////////////////////////////////
	//		POP CX   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x59){
		OP_CODE_1({
			ByteSetToWord(&reg->CX, *VMtoRM(Mem, reg->SS, reg->SP), *VMtoRM(Mem, reg->SS, reg->SP+1));
			reg->SP = reg->SP + 2;
		}, 
		{
			re->string = "POP CX";
		})
	};

	//////////////////////////////////////////////////
	//		POP DX   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x5A){
		OP_CODE_1({
			ByteSetToWord(&reg->DX, *VMtoRM(Mem, reg->SS, reg->SP), *VMtoRM(Mem, reg->SS, reg->SP+1));
			reg->SP = reg->SP + 2;
		}, 
		{
			re->string = "POP DX";
		})
	};
	
	//////////////////////////////////////////////////
	//		POP BX   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x5B){
		OP_CODE_1({
			ByteSetToWord(&reg->BX, *VMtoRM(Mem, reg->SS, reg->SP), *VMtoRM(Mem, reg->SS, reg->SP+1));
			reg->SP = reg->SP + 2;
		}, 
		{
			re->string = "POP BX";
		})
	};

	//////////////////////////////////////////////////
	//		POP SP   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x5C){
		OP_CODE_1({
			ByteSetToWord(&reg->SP, *VMtoRM(Mem, reg->SS, reg->SP), *VMtoRM(Mem, reg->SS, reg->SP+1));
			reg->SP = reg->SP + 2;
		}, 
		{
			re->string = "POP SP";
		})
	};

	//////////////////////////////////////////////////
	//		POP BP   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x5D){
		OP_CODE_1({
			ByteSetToWord(&reg->BP, *VMtoRM(Mem, reg->SS, reg->SP), *VMtoRM(Mem, reg->SS, reg->SP+1));
			reg->SP = reg->SP + 2;
		}, 
		{
			re->string = "POP BP";
		})
	};
	
	//////////////////////////////////////////////////
	//		POP SI   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x5E){
		OP_CODE_1({
			ByteSetToWord(&reg->SI, *VMtoRM(Mem, reg->SS, reg->SP), *VMtoRM(Mem, reg->SS, reg->SP+1));
			reg->SP = reg->SP + 2;
		}, 
		{
			re->string = "POP SI";
		})
	};

	//////////////////////////////////////////////////
	//		POP DI   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x5F){
		OP_CODE_1({
			ByteSetToWord(&reg->DI, *VMtoRM(Mem, reg->SS, reg->SP), *VMtoRM(Mem, reg->SS, reg->SP+1));
			reg->SP = reg->SP + 2;
		}, 
		{
			re->string = "POP DI+";
		})
	};
	
	//////////////////////////////////////////////////
	//		JO   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x70){
		BYTE byte = GetByteByIP(Mem, CS, IP);
		WORD ip = *IP + ByteToWord(byte);
		OP_CODE_IP_2({
			if (reg->GetOF() == 1)
			{
				reg->IP = ip;
			}
			else
			{
				reg->IP = *IP;
			}
		}, 
		{
			re->string = "JO " + WordToHexStr(ip);
		})
	};
	
	//////////////////////////////////////////////////
	//		JNO   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x71){
		BYTE byte = GetByteByIP(Mem, CS, IP);
		WORD ip = *IP + ByteToWord(byte);
		OP_CODE_IP_2({
			if (reg->GetOF() == 0)
			{
				reg->IP = ip;
			}
			else
			{
				reg->IP = *IP;
			}
		}, 
		{
			re->string = "JNO " + WordToHexStr(ip);
		})
	};
	
	//////////////////////////////////////////////////
	//		JB   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x72){
		BYTE byte = GetByteByIP(Mem, CS, IP);
		WORD ip = *IP + ByteToWord(byte);
		OP_CODE_IP_2({
			if (reg->GetCF() == 1)
			{
				reg->IP = ip;
			}
			else
			{
				reg->IP = *IP;
			}
		}, 
		{
			re->string = "JB " + WordToHexStr(ip);
		})
	};
	
	//////////////////////////////////////////////////
	//		JNB   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x73){
		BYTE byte = GetByteByIP(Mem, CS, IP);
		WORD ip = *IP + ByteToWord(byte);
		OP_CODE_IP_2({
			if (reg->GetCF() == 0)
			{
				reg->IP = ip;
			}
			else
			{
				reg->IP = *IP;
			}
		}, 
		{
			re->string = "JNB " + WordToHexStr(ip);
		})
	};
	
	//////////////////////////////////////////////////
	//		JE   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x74){
		BYTE byte = GetByteByIP(Mem, CS, IP);
		WORD ip = *IP + ByteToWord(byte);
		OP_CODE_IP_2({
			if (reg->GetZF() == 1)
			{
				reg->IP = ip;
			}
			else
			{
				reg->IP = *IP;
			}
		}, 
		{
			re->string = "JE " + WordToHexStr(ip);
		})
	};
	
	//////////////////////////////////////////////////
	//		JNE   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x75){
		BYTE byte = GetByteByIP(Mem, CS, IP);
		WORD ip = *IP + ByteToWord(byte);
		OP_CODE_IP_2({
			if (reg->GetZF() == 0)
			{
				reg->IP = ip;
			}
			else
			{
				reg->IP = *IP;
			}
		}, 
		{
			re->string = "JNE " + WordToHexStr(ip);
		})
	};
	
	//////////////////////////////////////////////////
	//		JBE   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x76){
		BYTE byte = GetByteByIP(Mem, CS, IP);
		WORD ip = *IP + ByteToWord(byte);
		OP_CODE_IP_2({
			if ( (reg->GetCF() == 1) || (reg->GetZF() == 10) )
			{
				reg->IP = ip;
			}
			else
			{
				reg->IP = *IP;
			}
		}, 
		{
			re->string = "JBE " + WordToHexStr(ip);
		})
	};
	
	//////////////////////////////////////////////////
	//		JA   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x77){
		BYTE byte = GetByteByIP(Mem, CS, IP);
		WORD ip = *IP + ByteToWord(byte);
		OP_CODE_IP_2({
			if ( (reg->GetCF() == 0) && (reg->GetZF() == 0) )
			{
				reg->IP = ip;
			}
			else
			{
				reg->IP = *IP;
			}
		}, 
		{
			re->string = "JA " + WordToHexStr(ip);
		})
	};
	
	//////////////////////////////////////////////////
	//		JS   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x78){
		BYTE byte = GetByteByIP(Mem, CS, IP);
		WORD ip = *IP + ByteToWord(byte);
		OP_CODE_IP_2({
			if (reg->GetSF() == 1)
			{
				reg->IP = ip;
			}
			else
			{
				reg->IP = *IP;
			}
		}, 
		{
			re->string = "JS " + WordToHexStr(ip);
		})
	};
	
	//////////////////////////////////////////////////
	//		JNS   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x79){
		BYTE byte = GetByteByIP(Mem, CS, IP);
		WORD ip = *IP + ByteToWord(byte);
		OP_CODE_IP_2({
			if (reg->GetSF() == 0)
			{
				reg->IP = ip;
			}
			else
			{
				reg->IP = *IP;
			}
		}, 
		{
			re->string = "JNS " + WordToHexStr(ip);
		})
	};

	//////////////////////////////////////////////////
	//		JL   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x7C){
		BYTE byte = GetByteByIP(Mem, CS, IP);
		WORD ip = *IP + ByteToWord(byte);
		OP_CODE_IP_2({
			if (reg->GetSF() != reg->GetOF())
			{
				reg->IP = ip;
			}
			else
			{
				reg->IP = *IP;
			}
		}, 
		{
			re->string = "JL " + WordToHexStr(ip);
		})
	};

	//////////////////////////////////////////////////
	//		JNL   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x7D){
		BYTE byte = GetByteByIP(Mem, CS, IP);
		WORD ip = *IP + ByteToWord(byte);
		OP_CODE_IP_2({
			if (reg->GetSF() == reg->GetOF())
			{
				reg->IP = ip;
			}
			else
			{
				reg->IP = *IP;
			}
		}, 
		{
			re->string = "JNL " + WordToHexStr(ip);
		})
	};
	
	//////////////////////////////////////////////////
	//		JG   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x7E){
		BYTE byte = GetByteByIP(Mem, CS, IP);
		WORD ip = *IP + ByteToWord(byte);
		OP_CODE_IP_2({
			if ( (reg->GetSF() == reg->GetOF()) && (reg->GetZF() == 0) ) 
			{
				reg->IP = ip;
			}
			else
			{
				reg->IP = *IP;
			}
		}, 
		{
			re->string = "JG " + WordToHexStr(ip);
		})
	};

	//////////////////////////////////////////////////
	//		JNG   
	//////////////////////////////////////////////////
	BindOpCodeCall(0x7F){
		BYTE byte = GetByteByIP(Mem, CS, IP);
		WORD ip = *IP + ByteToWord(byte);
		OP_CODE_IP_2({
			if ( (reg->GetSF() != reg->GetOF()) || (reg->GetZF() == 1) )
			{
				reg->IP = ip;
			}
			else
			{
				reg->IP = *IP;
			}
		}, 
		{
			re->string = "JNG " + WordToHexStr(ip);
		})
	};

}